﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;

namespace ZOVNP.Model.Abstracts
{
    /// <summary> Базовый интерфейс доменного объекта. </summary>
    /// <remarks> 
    /// Доменный объект характеризуется свои ключом - уникальным идентификатором, имеет определенное состояние и может быть отнесен к некоторому контексту (не более одному).
    /// Доменный объект может и не иметь своего контекста. Также доменный объект поддерживает интерфейс уведомления об изменении своих свойств. 
    /// </remarks>
    public interface IDomainObject : Fintech.Utils.IKeyable, INotifyPropertyChanging, INotifyPropertyChanged, ISelfPropertiesCheckable
    {
        #region Свойства

        /// <summary> Получить текущее состояние доменного объекта. </summary>
        EntityState EntityState { get; }

        /// <summary> Контекст, к которому принадлежит данный доменный объект. </summary>
        IDomainContext Context { get; }

        /// <summary> Расширенные присоединенные свойства объекта. </summary>
        /// <remarks> Эти свойства не участвуют в процессе обновления. </remarks>
        //Dictionary<string, object> ExtendedProperties { get; }

        bool New { get; }

        #endregion

        #region Методы

        /// <summary> Получение информации о максимальной длине строковых полей и полей-массивов для данного объекта. </summary>
        /// <param name="PropertyName"> Имя свойства, максимальную длину которого нужно получить. </param>
        /// <returns> Максимальная длина либо -1, если она не ограничена. </returns>
        int MaxLength(string PropertyName);

        /// <summary> Присоединить к объекту дополнительное свойство. </summary>
        /// <param name="PropertyName"> Имя свойства. </param>
        /// <param name="PropertyValue"> Значение свойства. </param>
        void AddProperty(string PropertyName, object PropertyValue);

        /// <summary> Получить присоединенное к объекту дополнительное свойство. </summary>
        /// <typeparam name="T"> Тип значения свойства. </typeparam>
        /// <param name="PropertyName"> Имя свойства. </param>
        /// <returns> Значение свойства. </returns>
        T GetProperty<T>(string PropertyName);

        /// <summary> Попытка получения присоединенного к объекту дополнительного свойства. </summary>
        /// <typeparam name="T"> Тип значения свойства. </typeparam>
        /// <param name="PropertyName"> Имя свойства. </param>
        /// <param name="PropertyValue"> Значение свойства. </param>
        /// <returns> true, если требуемое свойство обнаружено, иначе false. </returns>
        bool TryGetProperty<T>(string PropertyName, out T PropertyValue);

        /// <summary> Получить присоединенное к объекту дополнительное булево свойство. </summary>
        /// <param name="PropertyName"> Имя свойства. </param>
        /// <returns> Значение свойства. </returns>
        bool GetBoolProperty(string PropertyName);

        /// <summary> Получить присоединенное к объекту дополнительное строковое свойство. </summary>
        /// <param name="PropertyName"> Имя свойства. </param>
        /// <returns> Значение свойства. </returns>
        string GetStringProperty(string PropertyName);

        /// <summary> Получить присоединенное к объекту дополнительное целочисленное свойство. </summary>
        /// <param name="PropertyName"> Имя свойства. </param>
        /// <returns> Значение свойства.  </returns>
        int GetIntProperty(string PropertyName);

        #endregion
    }
}
